home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekikoh Dennoh Club 1
/
Gekikoh Dennoh Club Vol. 1 (Japan).7z
/
Gekikoh Dennoh Club Vol. 1 (Japan) (Track 1).bin
/
tools
/
cdc
/
src
/
cdrc__.c
< prev
next >
Wrap
Text File
|
1997-02-14
|
26KB
|
973 lines
#include "_TNB.c"
#define UNchar unsigned char
#define UNint unsigned int
extern int SCSI_ID;
extern int SCSI_IDF;
extern char SCSI_LUN;
extern short CddevSw; //0: SCSI直接 1:計測IOCTRL
extern short CddDrvNo; //計測IOCTRL用ドライヴNO
extern short SWPD; // /PD がある
extern short PauseMode; // 0:特に 1:ポーズ中
extern short Volum; // ボリューム
extern short DeviType; //5or4=CD-ROM 0x10=MD
extern short MD_SeqSecTrak; // 1;MD セパレートトラック有り
extern short MD_MonoTrak; // -1;MONOトラックのみ,1;有り(禁止),0;なし
extern short MD_PlayOnly; // 0;録再MEDIA 1;再生専用MEDIA
extern UNchar REQU_PTR_KEY;
extern UNchar REQU_PTR_ASC;
extern UNchar REQU_PTR_ASCQ;
static UNchar MDTOC[256];
#define MULU(o1,o2) ( (unsigned short)(o1)*(unsigned short)(o2) )
#define MULS(o1,o2) ( (short)(o1)*(short)(o2) )
#define TIMES(TT) ( __udivsi3( __mulsi3((TT),1000),979) )
#define TIMESR(TT) ( __udivsi3( __mulsi3((TT),979),1000) )
//#define FREMS(TT) ( __udivsi3( __mulsi3((TT),469),100) )
//#define FREMSR(TT) ( __udivsi3( __mulsi3((TT),100)+50,469) )
//#define FREMS(TT) ( MULU((TT),4800) / 1024 )
#define FREMS(TT) ( FREMS_TABLE[(TT)] )
#define FREMSR(TT) ( DIVU((TT)*1024+512,4800) )
UNchar FREMS_TABLE[16]={( 0*4800)/1024,( 1*4800)/1024,( 2*4800)/1024,( 3*4800)/1024,
( 4*4800)/1024,( 5*4800)/1024,( 6*4800)/1024,( 7*4800)/1024,
( 8*4800)/1024,( 9*4800)/1024,(10*4800)/1024,(11*4800)/1024,
(12*4800)/1024,(13*4800)/1024,(14*4800)/1024,(15*4800)/1024
};
/*------------------------------*/
/* 構造体 */
/*------------------------------*/
typedef struct {
int fg; /* 状態 0x11 演奏中,0x12 演奏中断 */
int track_no; /* 曲番号 */ /* 曲番号 ind*0x10000+track */
int time; /* 現在の演奏時間 */
int address; /* 演奏アドレス */
int track_long; /* 演奏中の曲のながさ*/
} PLYINF;
extern int CddevPauAdd;
extern int CddevPlaEnd;
extern short CddevPauseD;
extern int PlayingTimeMD;
extern UNchar buf2k[2336];
extern UNchar buf32[336];
/**************************************
低レベルルーチン
**************************************/
/*******************************
REZEROUNITコマンドを送る
********************************/
int ZeroUnit()
{
int r;
StpDsk();
if ( DeviType==0x10 ){
//MD
static UNchar com[]={0xD6,0,0,0,0, 0,0,0,0,0};
r=scsi_cmd( 10, com, 0 );
}
return( scsi_rezerounit(SCSI_ID) ); //LUNは指定なしないこと
}
/*******************************
ストップコマンドを送る
********************************/
int StpDsk()
{
int r;
#if 1
static UNchar com[]={0x4b,0,0,0,0, 0,0,0,0,0};
return( scsi_cmd( 10, com, 0 ) );
#else
if ( CddevSw==0 ){ //0: SCSI直接 1:計測IOCTRL
static UNchar com[]={0x4b,0,0,0,0, 0,0,0,0,0};
return( scsi_cmd( 10, com, 0 ) );
} else {
#if 1
cdd_ioctrl(0x8004,buf32);
//if ( buf32[0]!=0 ) /*演奏している?*/
// return(-1);
CddevPauAdd= buf32[8] * 0x10000 + buf32[9] * 0x100 + buf32[10];
#else
extern PLYINF plyinf;
//if ( plyinf.fg!=0x11 ) /*演奏している?*/
// return(-1);
ChkPly( &plyinf );
CddevPauAdd=plyinf.address;
#endif
cdd_ioctrl(0x8003,buf32);//停止
CddevPauseD=1;
//buf32[0]=0;
//cdd_ioctrl(0x8005,buf32);//停止
return(0);
}
#endif
}
/*******************************
Resume コマンドを送る
********************************/
int Resume()
{
#if 1
static UNchar com[]={0x4b,0,0,0,0, 0,0,0,1,0};
return( scsi_cmd( 10, com, 0 ) );
#else
if ( CddevSw==0 ){ //0: SCSI直接 1:計測IOCTRL
static UNchar com[]={0x4b,0,0,0,0, 0,0,0,1,0};
return( scsi_cmd( 10, com, 0 ) );
} else {
int i;
#if 0
cdd_ioctrl(0x8004,buf32);
if ( buf32[0]!=1 || CddevPauAdd==0 ) /*停止中?*/
return(-1);
#else
//extern PLYINF plyinf;
//if ( plyinf.fg!=0x12 ) /*演奏している?*/
// return(-1);
#endif
i=CddevPauAdd;
CddevPauAdd=0;
CddevPauseD=0;
return( PlyDsk( i,CddevPlaEnd ) );
}
#endif
}
/********************************
演奏状態を調べる
*********************************/
int ChkPly( PLYINF *plyinf )
{
int i,j,r;
if ( DeviType!=0x10 ){
if ( CddevSw==0 ){ //0: SCSI直接 1:計測IOCTRL
static UNchar com[]={
0x42, /* Read Sub-Channel Command */
0x02, /* Set MSF Bit */
0x40, /* Set SubQ Bit */
0x01, /* CD-ROM Current Posision */
0,
0,
0,
0,
16, /* Allocation Length */
0
};
if ( scsi_cmd( 10,com, 16, buf32 )!=0 )
return(-1);
plyinf->fg = buf32[1]&0x1F; /* 状態 */
plyinf->track_no = buf32[6] + buf32[7]*0x10000; /* 曲番号 ind*0x10000+track */
plyinf->time = (*(UNint*)&buf32[12]) & 0xFFFFFF;
plyinf->address = (*(UNint*)&buf32[8]) & 0xFFFFFF;
//plyinf->time = buf32[13] * 0x10000 + buf32[14] * 0x100 + buf32[15];
//plyinf->address = buf32[9] * 0x10000 + buf32[10] * 0x100 + buf32[11];
} else {
cdd_ioctrl(0x8004,buf32);
if ( buf32[0]==0 && buf32[1]==0 )/*CD入っていないらしい*/
return(-1);
#if 0
if ( buf32[0]==0 && buf32[1]==1 )
plyinf->fg = 0x11;
else if ( buf32[0]==1 && buf32[1]==1 )
plyinf->fg = 0x13;
else plyinf->fg = 0x15;
#endif
if ( CddevPauseD==0 ){ // 0:特に 1:ポーズ中
if ( buf32[0]==0 && buf32[1]==1 )
plyinf->fg = 0x11;
else if ( buf32[0]==1 && buf32[1]==1 )
plyinf->fg = 0x13;
else plyinf->fg = 0x15;
} else plyinf->fg = 0x12;
plyinf->track_no = buf32[2] + buf32[3]*0x10000; /* 曲番号 ind*0x10000+track */
plyinf->time = (*(UNint*)&buf32[4])/0x100;
plyinf->address = (*(UNint*)&buf32[8])/0x100;
//plyinf->time = buf32[4] * 0x10000 + buf32[5] * 0x100 + buf32[6];
//plyinf->address = buf32[8] * 0x10000 + buf32[9] * 0x100 + buf32[10];
}
} else {
//MD
static UNchar com[]={ 0xD7,0,0,0,0, 0,0,0,4,0 };
//extern int (*pListLong)[]; // ながさ時間
com[1]=0;
PlayingTimeMD=-1;
for(i=0;i<3;i++){
r=scsi_cmd( 10, com, 4, buf32 );
if ( r==0 )
break;
if ( (REQU_PTR_KEY&0xF)==5 ){
//コマンドエラー と言うことは・・・
i=scsi_testunit(SCSI_IDF);
if ( REQU_PTR_ASC==0x3a ) //メディアが入っていない!!
return(-1);
plyinf->fg = 0x13; /* 停止 */
return(0);
}
if ( (REQU_PTR_KEY&0xF)!=2 )
break;
}
if ( r!=0 ){
plyinf->fg = 0x13; /* 停止 */
} else {
if ( scsi_testunit(SCSI_IDF)==2 ){
if ( (REQU_PTR_KEY&0xF)==2 && REQU_PTR_ASC==0x00 )
plyinf->fg = REQU_PTR_ASCQ;
} else {
// testunit で 2 出ないと困る・・・
plyinf->fg = 0x11; /* 演奏中 */
}
}
r=*(int*)buf32;
if ( MD_PlayOnly==0 ) // 0;録再MEDIA 1;再生専用MEDIA
r-=0x320000;
r=r/0x100;
r=(r/0x100*0x20)+(r&0x1F); //アドレス
r=TIMES(r); //補正後のアドレス
//-- 相対アドレス(MSF型に変換)
plyinf->address = DIVU(r/0x10,60)*0x10000 + MODU(r/0x10,60)*0x100 + FREMS(r&0xF);
if ( MD_MonoTrak!=0 ){ // -1;MONOトラックのみ,1;有り(禁止),0;なし
//モノラルトラック
plyinf->address = addtime( plyinf->address,plyinf->address );
}
//-- 演奏開始からの時間
com[1]=1;
if ( scsi_cmd( 10, com, 4, &PlayingTimeMD ) )
if ( scsi_cmd( 10, com, 4, &PlayingTimeMD ) )
if ( scsi_cmd( 10, com, 4, &PlayingTimeMD ) )
PlayingTimeMD=-1;
//-- アドレス(MSF型に変換)
// track_no & time も計算
CPD_MDSUB( plyinf ); //adのみから計算
if ( MD_MonoTrak!=0 ){ // -1;MONOトラックのみ,1;有り(禁止),0;なし
//モノラルトラック
plyinf->time = addtime( plyinf->time,plyinf->time );
}
}
return(0);
}
/*********************************
(トラック)演奏開始からのS(MD専用)
*********************************/
int MDPlayingTimeChk()
{
static UNchar com[]={ 0xD7,1,0,0,0, 0,0,0,4,0 };
int tim;
if ( DeviType!=0x10 )
return(0);
if ( scsi_cmd( 10, com, 4, &tim ) )
if ( scsi_cmd( 10, com, 4, &tim ) )
return(0);
if ( tim<10 )
return(-1);
return(0);
}
/*********************************
演奏させる
*********************************/
int PlyDsk( int start , int stop )
{
UNchar com[12];
if ( DeviType!=0x10 ){
if ( CddevSw==0 ){ //0: SCSI直接 1:計測IOCTRL
#if 1
com[0] = 0x47; /* Play Audio MSF Command */
com[1] = 0;
com[2] = 0;
com[3] = ( start / 0x10000 ) & 0xff;
com[4] = ( start / 0x100 ) & 0xff;
com[5] = start & 0xff;
com[6] = ( stop / 0x10000 ) & 0xff;
com[7] = ( stop / 0x100 ) & 0xff;
com[8] = stop & 0xff;
com[9] = 0;
return( scsi_cmd( 10, com, 0 ) );
#else
int s,e;
s=MULU((start/0x10000)&0xff,75*60)
+MULU((start/0x100)&0xff,75)
+(start&0xff);
e=MULU((stop/0x10000)&0xff,75*60)
+MULU((stop/0x100)&0xff,75)
+(stop&0xff);
e=e-s;
com[0] = 0xA5; /* Play Audio Command */
com[1] = 0;
*(int*)&(com[2]) = s;
*(int*)&(com[6]) = e;
com[10] = 0;
com[11] = 0;
return( scsi_cmd( 12, com, 0 ) );
#endif
} else {
com[0] = ( start / 0x10000 ) & 0xff;
com[1] = ( start / 0x100 ) & 0xff;
com[2] = start & 0xff;
com[3] = 0;
com[4] = ( stop / 0x10000 ) & 0xff;
com[5] = ( stop / 0x100 ) & 0xff;
com[6] = stop & 0xff;
com[7] = 0;
cdd_ioctrl(0x8001,com);
CddevPlaEnd=stop;
CddevPauseD=0;
return( 0 );
}
} else {
// MD ★★★★怪しいい・・・
int i,j,l,sa,ea;
// スタートアドレス : MSF -> 論理アドレス
sa = MDMSF2ADDS(start);
sa+=1;
// エンドアドレス : MSF -> 論理アドレス
ea = MDMSF2ADDS(stop);
// 長さ計算
l=ea-sa -1;
// CDB 制作
com[0] = 0x45; /* Play Audio ADDS Command */
com[1] = 0;
com[2] = 0;
com[3] = ( sa / 0x10000 ) & 0xff;
com[4] = ( sa / 0x100 ) & 0xff;
com[5] = sa & 0xff;
com[6] = 0;
com[7] = ( l / 0x100 ) & 0xff;
com[8] = l & 0xff;
com[9] = 0;
return( scsi_cmd( 10, com, 0 ) );
}
}
/*+++++++++*/
int PlyDsk_hf( int start , int stop )
{
/* Play Audio MSF Command */
UNchar com[10];
if ( DeviType!=0x10 ){
if ( CddevSw==0 ){ //0: SCSI直接 1:計測IOCTRL
com[0] = 0x47; /* Play Audio MSF Command */
com[1] = 0;
com[2] = 0;
com[3] = ( start / 0x10000 ) & 0xff;
com[4] = ( start / 0x100 ) & 0xff;
com[5] = start & 0xff;
com[6] = ( stop / 0x10000 ) & 0xff;
com[7] = ( stop / 0x100 ) & 0xff;
com[8] = stop & 0xff;
com[9] = 0;
return( scsi_cmd_hf( 10, com, 0 ) );
}
return( PlyDsk( start,stop ) );
} else {
// MD ★★★★怪しいい・・・
int i,j,l,sa,ea;
// スタートアドレス : MSF -> 論理アドレス
sa = MDMSF2ADDS(start);
sa+=1;
// エンドアドレス : MSF -> 論理アドレス
ea = MDMSF2ADDS(stop);
// 長さ計算
l=ea-sa -1;
// CDB 制作
com[0] = 0x45; /* Play Audio ADDS Command */
com[1] = 0;
com[2] = 0;
com[3] = ( sa / 0x10000 ) & 0xff;
com[4] = ( sa / 0x100 ) & 0xff;
com[5] = sa & 0xff;
com[6] = 0;
com[7] = ( l / 0x100 ) & 0xff;
com[8] = l & 0xff;
com[9] = 0;
return( scsi_cmd_hf( 10, com, 0 ) );
}
}
/*+++++++++++++*/
int MDMSF2ADDS(ad)
int ad;
{
int i,j,r;
i=(ad/0x10000)&0xFF;
j=(ad/0x100) &0xFF;
r=(MULU(i,60)+j)*0x10 + FREMSR(ad&0xFF);
r=TIMESR(r); //MD 上のアドレスに変換
return( r );
}
/***********************************
トラック演奏(MD用・・・)
************************************/
int PlyDskTrack( int start , int stop )
{
static UNchar com[]={0x48,0,0,0x00,0, 0,0,0x00,0,0};
com[4] = start;
com[7] = stop;
return( scsi_cmd( 10, com, 0 ) );
}
/*++++*/
int PlyDskTrack_hf( int start , int stop )
{
static UNchar com[]={0x48,0,0,0x00,0, 0,0,0x00,0,0};
com[4] = start;
com[7] = stop;
return( scsi_cmd_hf( 10, com, 0 ) );
}
/***********************************
曲数と最終演奏アドレスを求める
************************************/
int RedTOC(leadout_address,min_,max_)
int *leadout_address,*min_,*max_;
{
int l;
if ( DeviType!=0x10 ){
static UNchar com[]={
/* Leadout Track Address get & Min. Max Track get */
0x43, /* scsi2 ReadTOC Command */
0x02, /* Set MSF Bit */
0,
0,
0,
0,
0xaa, /* LeadoutOut Track */
0,
12, /* Allocation Length */
0
};
if ( CddevSw==0 ){ //0: SCSI直接 1:計測IOCTRL
if( scsi_cmd( 10, com, 12, buf32 )!=0 )
return(-1);
*leadout_address = (*(UNint*)&buf32[8]) & 0xFFFFFF;
//*leadout_address = buf32[9] * 0x10000 + buf32[10] * 0x100 + buf32[11];
*min_ = buf32[2]; /* Min. Track */
*max_ = buf32[3]; /* Max. Track */
} else {
cdd_ioctrl(0x8000,buf32);
*leadout_address = (*(UNint*)&buf32[2]) / 0x100;
//*leadout_address = buf32[2] * 0x10000 + buf32[3] * 0x100 + buf32[4];
*min_ = buf32[0]; /* Min. Track */
*max_ = buf32[1]; /* Max. Track */
}
} else {
static UNchar com[]={0xD1,0x00,0,0,0,0x00,0,0x09,0x20,0};
int i,j,r,o;
int t,tt;
int lst[100];
int lstl[100];
UNchar *fg;
*min_ = 1; /* Min. Track */
*max_ = 1; /* Max. Track */
*leadout_address=0;
MD_PlayOnly=0; // 0;録再MEDIA 1;再生専用MEDIA
com[0]=0xD1;
if ( (r=scsi_cmd( 10, com, 2336, buf2k ))!=0 )
r=scsi_cmd( 10, com, 2336, buf2k );
if ( r==2 ){
if ( (REQU_PTR_KEY&0xF)==5 && REQU_PTR_ASC==0x20 && REQU_PTR_ASCQ==0 ){
MD_PlayOnly=1; // 0;録再MEDIA 1;再生専用MEDIA
com[0]=0xD4;
if ( (r=scsi_cmd( 10, com, 2336, buf2k ))!=0 )
if ( (r=scsi_cmd( 10, com, 2336, buf2k ))!=0 )
return(-1);
} else {
return(-1);
}
//if ( (REQU_PTR_KEY&0xF)==2 && REQU_PTR_ASC==0x57 && REQU_PTR_ASCQ==0 )
// return(-1);
} else if ( r!=0 ){
return(-1);
}
*max_ = l = buf2k[0x0F]; /* Max. Track */
if ( MD_PlayOnly==0 ){ // 0;録再MEDIA 1;再生専用MEDIA
//====== 録再 ======
//----- フラグクリア
fg=lstl; //チョット借りる
j=0xFFFFFF;
for(t=1;t<=254;t++){
fg[t]=0;
// ついでに一番若いセクタを指しているテーブルを探す
o=0x130+(t-1)*8;
i=buf2k[o]*0x10000 + buf2k[o+1]*0x100 + buf2k[o+2];
if ( i>=0xC800 && i<j ){
j=i;
tt=t;
}
}
//----- 曲の列びをチェック
for(t=1;t<=l;t++){
j=buf2k[0x20+t-1]; //ofset
o=0x130+(j-1)*8; //ofset
// +7 のバイトを見てみる
if ( buf2k[o+7]==0 && fg[j]==0 ){
MDTOC[t]=j;
fg[j]=1;
continue;
}
// 0以外。未使用FATかな?
// 未使用のようなので、
if ( j!=t ){
// TrkNo と テーブルが違う場合
// TrkNo で見てみる
o=0x130+(t-1)*8; //ofset
if ( buf2k[o+7]==0 && fg[t]==0 ){
// 使えるようだ
MDTOC[t]=t;
fg[t]=1;
continue;
}
}
// 頭の方から使っていない番号を見つける
// ★★これでもない場合...間違っているわけだ・・・
for(i=1;i<=254;i++){
if ( fg[i]!=0 )
continue;
o=0x130+(i-1)*8; //ofset
if ( buf2k[o+7]==0 ){
// 使えるようだ
MDTOC[t]=i;
fg[i]=1;
break;
}
}
}
if ( fg[tt]==0 ){
// 一番若いセクタのが使われていない!
// 一番最初の曲に当てがう
MDTOC[1]=tt;
}
} else {
//====== 再生専用 ======
;
}
//fprintf_(1,"%3\r\n",tt);
if ( Music_inf_all( 1,l,lst,lstl ) )
if ( Music_inf_all( 1,l,lst,lstl ) )
return(-1);
j=0;
for(i=1;i<=l;i++)
j=addtime_( j,lstl[i] );
*leadout_address = j;
}
return(0);
}
/*************************************
演奏アドレスを求める
[MD] MD の場合、先にRedTOCを実
行しておかなければならないが、
問題無い様
***************************************/
int Music_inf( track_no,start_address,track_long )
int track_no;
int *start_address,*track_long;
{
int i,oo,o;
int j,l,r;
int fg;
if ( DeviType!=0x10 ){
static UNchar com[]={
0x43, /* scsi2 ReadTOC Command */
0x02, /* Set MSF Bit */
0,
0,
0,
0,
00, /* Set Start Track */
0,
12, /* Allocation Length */
0
};
if ( CddevSw==0 ){ //0: SCSI直接 1:計測IOCTRL
com[6] = (UNchar)track_no; /* Set Start Track */
if( scsi_cmd( 10, com, 12, buf32 ) != 0 )
return(-1);
*start_address = (*(UNint*)&buf32[8]) & 0xFFFFFF;
//*start_address = buf32[9] * 0x10000 + buf32[10] * 0x100 + buf32[11];
if ( (buf32[5]&0b0100)!=0 )//データだ
*(UNint*)start_address |= (UNint)0x80000000;
} else {
cdd_ioctrl(0x8000,buf2k);
i=(track_no-1)*4+6;
*start_address = (*(UNint*)&buf2k[i]) / 0x100;
//*start_address = buf2k[i] * 0x10000 + buf2k[i+1] * 0x100 + buf2k[i+2];
if ( buf2k[i+3]!=0 )//データだ
*(UNint*)start_address |= (UNint)0x80000000;
}
} else {
static UNchar com[]={0xD1,0x00,0,0,0, 0x00,0,0x09,0x20,0};
if ( MD_PlayOnly==0 ) // 0;録再MEDIA 1;再生専用MEDIA
com[0]=0xD1;
else com[0]=0xD4;
if ( scsi_cmd( 10, com, 2336, buf2k )!=0 ){
if ( scsi_cmd( 10, com, 2336, buf2k )!=0 ){
*start_address = 0;
if ( track_long!=0 )
*track_long = 0;
return(-1);
}
}
if ( MD_PlayOnly==0 ){ // 0;録再MEDIA 1;再生専用MEDIA
//===== 録音再生 ======
//o=buf2k[0x20-1+track_no]; //ofset
//o=track_no;
o=MDTOC[track_no];
o=0x130+(o-1)*8; //ofset
//セクタの先頭
//j=buf2k[o]*0x10000+buf2k[o+1]*0x100+buf2k[o+2];
j=(*(int*)&buf2k[o])/0x100;
j=(j-0xC800)/32; //定数?
i=TIMES(j);
i=DIVU(i/0x10,60)*0x10000 + MODU(i/0x10,60)*0x100 + FREMS(i&0x0F);
*start_address = i;
if ( track_long!=0 ){
//i=buf2k[o+4]*0x10000+buf2k[o+4+1]*0x100+buf2k[o+4+2];
i=(*(int*)&buf2k[o+4])/0x100;
i=(i-0xC800)/32; //定数?
l=TIMES( i-j );
fg=0;
if ( buf2k[o+7]!=0 ){
//続きのセクタがある!?
//★今のところ、判らない?!
// 書かれている数値が続きセクタ+αとする・・・
oo=buf2k[o+7];
oo=0x120+(oo)*8; //ofset
//セクタの先頭
//j=buf2k[oo]*0x10000+buf2k[oo+1]*0x100+buf2k[oo+2];
j=(*(int*)&buf2k[oo])/0x100;
j=(j-0xC800)/32; //定数?
//セクタの終わり
//i=buf2k[oo+4]*0x10000+buf2k[oo+4+1]*0x100+buf2k[oo+4+2];
i=(*(int*)&buf2k[oo+4])/0x100;
i=(i-0xC800)/32; //定数?
i=TIMES( i-j );
l+=i;
fg=-1;
}
i=DIVU(l/0x10,60)*0x10000 + MODU(l/0x10,60)*0x100 + FREMS(l&0x0F);
*track_long= i;
if ( (buf2k[o+3]&0x0F)==4 ){
// MONO トラック!
*start_address = addtime( *start_address,*start_address);
*track_long = addtime( *track_long,*track_long );
*track_long |= 0x20000000; //MONOトラックフラグ
}
if ( fg!=0 )
*track_long |= 0x40000000; //セパレートセクタフラグ
}
if ( (buf2k[o+3]&0xF0)==0xA0 ){
// デジタル録音されている $Ax
*start_address |= 0x40000000; //デジタルフラグ
}
} else {
//===== 再生専用 ======
o=0x120+(track_no)*8; //ofset
j=(*(int*)&buf2k[o])/0x100;
j=(j-0x01F0)/32; //定数?
i=TIMES(j);
i=DIVU(i/0x10,60)*0x10000 + MODU(i/0x10,60)*0x100 + FREMS(i&0x0F);
*start_address = i;
if ( track_long!=0 ){
//i=buf2k[o+4]*0x10000+buf2k[o+4+1]*0x100+buf2k[o+4+2];
i=(*(int*)&buf2k[o+4])/0x100;
i=(i-0x01F0)/32; //定数?
l=TIMES( i-j );
i=DIVU(l/0x10,60)*0x10000 + MODU(l/0x10,60)*0x100 + FREMS(l&0x0F);
*track_long= i;
if ( (buf2k[o+3]&0x0F)==4 ){
// MONO トラック!
*start_address = addtime( *start_address,*start_address);
*track_long = addtime( *track_long,*track_long );
*track_long |= 0x20000000; //MONOトラックフラグ
}
}
if ( (buf2k[o+3]&0xF0)==0xA0 ){
// デジタル録音されている $Ax
*start_address |= 0x40000000; //デジタルフラグ
}
}
}
return(0);
}
/*++++++++++*/
int Music_inf_all( min,max,lst,lstl )
int min,max;
int *lst,*lstl;
{
int i;
int t;
if ( DeviType!=0x10 ){
if ( CddevSw==0 ){ //0: SCSI直接 1:計測IOCTRL
for(t=min;t<=max;t++){
if ( Music_inf( t,&lst[t],0 )!=0 )
return(-1);
}
} else {
cdd_ioctrl(0x8000,buf2k);
for(t=min;t<=max;t++){
i=(t-1)*4+6;
lst[t]= (*(UNint*)&buf2k[i]) / 0x100;
//lst[t]= buf2k[i] * 0x10000 + buf2k[i+1] * 0x100 + buf2k[i+2];
if ( buf2k[i+3]!=0 )//データだ
(UNint)lst[t] |= (UNint)0x80000000;
}
}
} else {
for(t=min;t<=max;t++){
if ( Music_inf( t,&lst[t],&lstl[t] )!=0 )
return(-1);
}
}
return(0);
}
/*************************************
トラックの文字をゲット
(文字数は 1700 の可能性有り)
***************************************/
int GetTrackName( int track_no, UNchar *nb )
{
static UNchar com[]={0xD1,0x00,0,0,0, 0x01,0,0x09,0x20,0};
int i,j,r,o;
UNchar *s;
nb[0]=0;
if ( MD_PlayOnly==0 ) // 0;録再MEDIA 1;再生専用MEDIA
com[0]=0xD1;
else com[0]=0xD4;
if ( scsi_cmd( 10, com, 2336, buf2k )!=0 )
if ( scsi_cmd( 10, com, 2336, buf2k )!=0 )
return(-1);
if ( MD_PlayOnly==0 ){ // 0;録再MEDIA 1;再生専用MEDIA
o=buf2k[0x20+track_no]; //ofset
if ( track_no!=0 && o==0 )
return(-1);
j=0;
for(;;){
s=&buf2k[0x120+o*8]; //ofset
for(i=0;i<7;i++){
if ( j<39 )
nb[j++]=*s++;
}
o=buf2k[0x120+o*8 +7]; //次の場所
if ( o==0 || j>=39 )
break;
}
nb[j]=0;
} else {
o=buf2k[0x20+track_no]; //ofset
if ( track_no!=0 && o==0 )
return(-1);
s=&buf2k[0x120+o*8]; //ofset
for(j=0;j<39;j++){
if ( (nb[j]=*s++)==0 )
break;
}
nb[j]=0;
}
return(0);
}
/*************************************
STARTSTOP
***************************************/
int scsi_startstop(cm)
int cm;
{
static UNchar com[6]={0x1B,0x1,0,0,0,0};
if ( cm==2 && DeviType==0x10 ){
//MD
static UNchar com[]={0xD6,0,0,0,0, 0,0,0,0,0};
scsi_cmd( 10, com, 0 );
}
com[4]=cm;
return( scsi_cmd( 6, com, 0 ) );
}
/*************************************
STARTSTOP__
***************************************/
void ejeload()
{
static UNchar com[6]={0x1B,0x1,0,0,0,0};
short i;
com[4]=2;
scsi_cmd( 6, com, 0 );
i=*(short *)0xe9a005; //wait
i=*(short *)0xe9a005;
i=*(short *)0xe9a005;
i=*(short *)0xe9a005;
i=*(short *)0xe9a005;
i=*(short *)0xe9a005;
com[4]=3;
scsi_cmd( 6, com, 0 );
}
/*-------------------------------------------------------------
ボリューム,パン関係
---------------------------------------------------------------*/
#define CDROMPage 0x0e // modesense/selectの時のページ
#define MDDATAPage 0x21 // modesense/selectの時のページ
#define SD_CURRENT 0x00 // sense data current
#define SD_CHANGE 0x40 // sense data changeable
#define SD_DEFAULT 0x80 // sense data defualt
#define SD_SAVE 0xc0 // sense data saveable
/************************************
今のVOL値を拾う
************************************/
int NowVol()
{
int pg;
UNchar buf[16+12];
pg=( DeviType!=0x10 )? CDROMPage : MDDATAPage;
if ( scsi_modesense( pg|SD_CURRENT,16+12,SCSI_IDF,buf )<0 )
return(-1);
return(buf[9+12]); //ポート0のボリューム
}
/************************************
VOL値を変更
************************************/
int ChnVol(vv)
int vv;
{
int i;
i=ChnVol_(vv);
if ( i>=0 )
Volum=vv;
return(i);
}
/*+++++++*/
int ChnVol_(vv)
int vv;
{
UNchar chk[16+12];
UNchar buf[16+12];
int i,j,r,pg;
pg=( DeviType!=0x10 )? CDROMPage : MDDATAPage;
if ( scsi_modesense( pg|SD_CURRENT,16+12,SCSI_IDF,buf )<0 )
return(-1);
r=buf[9+12]; //ポート0のボリューム
if ( scsi_modesense( pg|SD_CHANGE,16+12,SCSI_IDF,chk )<0 )
return(-1);
for(i=0;i<4;i++){
j=9+12+i*2;
if ( chk[j]==0xFF )
buf[j]=vv;
}
buf[2+12]=4;
buf[8]= buf[9]= buf[10]= buf[11]= 0;
if ( scsi_modeselect(0x10,16+4,SCSI_IDF,&buf[8])<0 )
return(-1);
return(r);
}
/************************************
CDROMのデフォルト値
************************************/
int DefVol()
{
UNchar buf[16+12];
int i,j,r,pg;
pg=( DeviType!=0x10 )? CDROMPage : MDDATAPage;
if ( scsi_modesense( pg|SD_DEFAULT,16+12,SCSI_IDF,buf )<0 )
return(-1);
return( buf[9+12] ); //ポート0のボリューム
}
/************************************
ステレオ <-> モノラル
************************************/
int ChnStMono()
{
UNchar buf[16+12];
int i,j,r,pg;
pg=( DeviType!=0x10 )? CDROMPage : MDDATAPage;
if ( scsi_modesense( pg|SD_CURRENT,16+12,SCSI_IDF,buf )<0 )
return(-1);
r=buf[8+12]; //ポート0のチャネル
if ( r!=1 ){
//モノラルだった ステレオに
buf[12+8]=0x01;
buf[12+10]=0x02;
} else {
//ステレオだった モノラルに
buf[12+8]=0x03;
buf[12+10]=0x03;
}
buf[2+12]=4;
buf[8]= buf[9]= buf[10]= buf[11]= 0;
if ( scsi_modeselect(0x10,16+4,SCSI_IDF,&buf[8])<0 )
return(-1);
return(r);
}
/***************************************
CD-ROM接続チェック
[戻り値] 0:OK
-1:
***************************************/
int CDROM_chk()
{
int i;
i=DEVICE_chk();
if ( i!=0 )
return(i);
/* 装置動作可能かチェック */
//i=1はCDC特有の戻り値なのだ
//REQU_PTR
i=scsi_testunit(SCSI_IDF);
if( i==0 || i==1 ){
return(0); //puts("OK! 1\n\r");
}
i=scsi_testunit(SCSI_IDF);
if( i==0 || i==1 ){
return(0); //puts("OK! 2\n\r");
}
i=scsi_testunit(SCSI_IDF);
if( i==0 || i==1 ){
return(0); //puts("OK! 3\n\r");
}
if ( DeviType==0x10 ){
if ( i==2 && REQU_PTR_ASC==0x00 && (REQU_PTR_ASCQ>=0x11 && REQU_PTR_ASCQ<=0x15) )
return(0); //puts("OK! 3\n\r");
}
//puts("指定された CD-ROM が準備されていません。\n\r");
return(-2);
}
/***************************************
DEVICE チェック!
***************************************/
int DEVICE_chk()
{
int i;
UNchar buf[0x24];
DeviType=5;
/* メディアチェック */
i=scsi_inquiry( 0x24, SCSI_IDF, (struct _inquiry *)buf );
for(;i==8;)
i=scsi_inquiry( 0x24, SCSI_IDF, (struct _inquiry *)buf );
if( SWPD==0 ){
if ( i!=0 ){
//puts("指定された SCSI-ID の装置は、現在動作不可能です。\n\r");
return(-3);
}
if ( buf[8]=='S' && buf[9]=='O' && buf[10]=='N' && buf[11]=='Y'
&& buf[16]=='M' && buf[17]=='D' && (buf[0]==7||buf[0]==0x10) ){
/* MDDATA だ!!*/
buf[0]=0x10; //5or4=CD-ROM 0x10=MD
} else if ( buf[0]!=0x05 && buf[0]!=0x04 ){
//puts("指定された SCSI-ID の装置は、CD-ROM ではない。\n\r");
return(-1);
}
} else if ( i!=0 ){ //PD対策
//puts("指定された SCSI-ID の装置は、現在動作不可能です。\n\r");
return(-3);
}
DeviType=buf[0];
return(0);
}